﻿Imports ATS.Business.Entities
Imports ATS.Data
Imports System.Transactions
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

Public Class UserTableComponent
    Dim key As String = "ATSbyJOKOforGENCPROSv2.1"
#Region "CRUD"
    Public Function CreateUser(userDetails As UserTable) As UserTable
        Return CreateNewUser(userDetails)
    End Function

    Public Function ReadUserDetails(_username As String) As UserTable
        ' Retrieve data.
        Dim dac As New AssetDataAccess()
        Try
            Return dac.GetUserDetails(_username)
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try
    End Function

    Public Function GetAllUsers() As List(Of UserTable)
        Dim dac As New AssetDataAccess()
        Try
            Return dac.GetAllUsers()
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try
    End Function

    Public Function UpdateUserDetails(userDetails As UserTable) As UserTable
        Return UpdateUserRecord(userDetails)
    End Function

    Public Function UpdatePassword(userDetails As UserTable) As UserTable
        With userDetails
            .AccountLocked = False
        End With
        Return UpdateUserRecord(userDetails)
    End Function

    Public Sub DeleteUser(userDetails As UserTable)
        Dim dac As New AssetDataAccess

        If Not ReadUserDetails(userDetails.Username) Is Nothing Then
            userDetails.Hashed = ReadUserDetails(userDetails.Username).Hashed
        Else
            Throw New Exception("Nothing to delete.")
        End If


        Try
            dac.DeleteUser(userDetails)
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try

    End Sub

    Public Function UserExists(_username As String) As Boolean
        Dim dac As New AssetDataAccess()
        Try
            If Not dac.GetUserDetails(_username) Is Nothing Then
                Return True
            Else
                Return False
            End If
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try
    End Function
#End Region

#Region "Support Procedures"
    Private Function decryptPassword(ByVal password As String) As String
        Dim decryptedPW As String = Nothing
        Dim tripleDes As New tripleDes
        tripleDes.secretKey = key
        tripleDes.encryptedData = password
        If tripleDes.decryptdata() Then
            Return tripleDes.data
        Else
            Throw New Exception("Invalid Operation. Key not found.")
        End If


    End Function
    Private Function UpdateUserRecord(ByVal userDetails As UserTable) As UserTable

        Using ts As New TransactionScope(TransactionScopeOption.Required)
            Try
                Dim saltUsed As Byte() = GENCPROS.Authenticate.EncryptDecrypt.ComputeSalt
                With userDetails
                    .Hashed = GENCPROS.Authenticate.EncryptDecrypt.ComputeHash(decryptPassword(userDetails.Hashed), "SHA512", saltUsed)
                    .Salt = Convert.ToBase64String(saltUsed)
                End With
                userDetails = UpdateUser(userDetails)
                ts.Complete()
            Catch ex As TransactionAbortedException
                Console.WriteLine("TransactionAbortedException Message: {0}", ex.Message)
                Throw ex
            Catch ex As ApplicationException
                Console.WriteLine("ApplicationException Message: {0}", ex.Message)
                Throw ex
            Catch ex As Exception
                Console.WriteLine(ex.Message)
                Throw ex
            End Try
        End Using

        Return userDetails
    End Function

    Private Function CreateNewUser(userdetails As UserTable) As UserTable
        ' Create new user
        Dim dac As New AssetDataAccess()
        Try
            Dim saltUsed As Byte() = GENCPROS.Authenticate.EncryptDecrypt.ComputeSalt
            With userdetails
                .Hashed = GENCPROS.Authenticate.EncryptDecrypt.ComputeHash(decryptPassword(userdetails.Hashed), "SHA512", saltUsed)
                .Salt = Convert.ToBase64String(saltUsed)
            End With
            Return dac.CreateUser(userdetails)
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try
    End Function

    Private Function UpdateUser(ByVal userDetails As UserTable) As UserTable
        ' Business logic.
        userDetails.LastPasswordChangeDateTime = Now

        ' Persist data.
        Dim dac As New AssetDataAccess()
        Try
            dac.UpdateUserTable(userDetails)
        Catch ex As Exception
            Console.WriteLine(ex.Message)
            Throw ex
        End Try

        Return userDetails
    End Function
#End Region
End Class
